<template>
  <el-form ref="form" label-width="110px">
    <el-form-item label="SPU名称">
      <el-input v-model="formData.spuName" placeholder="请输入SPU名称"></el-input>
    </el-form-item>
    <el-form-item label="SPU品牌">
      <el-select style="width: 240px" v-model="formData.tmId" placeholder="请输入SPU品牌">
        <el-option
          v-for="tm in allTrademark"
          :key="tm.id"
          :label="tm.tmName"
          :value="tm.id"
        ></el-option>
      </el-select>
    </el-form-item>
    <el-form-item label="SPU描述">
      <el-input
        type="textarea"
        v-model="formData.description"
        placeholder="请输入SPU描述"
      ></el-input>
    </el-form-item>
    <el-form-item label="SPU照片">
      <!-- 
        图片上传服务器成功后，会自动放入imgList中 
        删除照片时，自动从imgList中移除
      -->
      <el-upload
        v-model:file-list="imgList"
        action="/api/admin/product/fileUpload"
        list-type="picture-card"
        :on-preview="handlePictureCardPreview"
        :on-remove="handleRemove"
        :before-upload="handlerUpload"
      >
        <el-icon>
          <Plus />
        </el-icon>
      </el-upload>
      <el-dialog v-model="dialogVisible">
        <img
          w-full
          :src="dialogImageUrl"
          alt="Preview Image"
          style="width: 100%; height: 100%"
        />
      </el-dialog>
    </el-form-item>
    <el-form-item label="SPU销售属性">
      <!-- 展示销售属性的下拉框 -->
      <el-select style="width: 240px" v-model="selectedSaleAttr" :placeholder="tipInfo">
        <el-option
          v-for="saleAttr in unSelectSaleAttr"
          :key="saleAttr.id"
          :label="saleAttr.name"
          :value="`${saleAttr.id}:${saleAttr.name}`"
        ></el-option>
      </el-select>
      <el-button
        :disabled="!selectedSaleAttr"
        style="margin-left: 10px"
        type="primary"
        icon="Plus"
        @click="addSaleAttr"
        >添加销售属性</el-button
      >
      <!-- 展示销售属性和属性值 -->
      <el-table :data="spuSaleAttr" style="margin-top: 10px" border>
        <el-table-column type="index" label="序号" align="center" width="100px">
        </el-table-column>
        <el-table-column
          prop="saleAttrName"
          label="销售属性名字"
          align="center"
          width="140px"
        >
        </el-table-column>
        <el-table-column label="销售属性值" align="center">
          <template #="{ row }">
            <el-tag
              style="margin: 0px 5px"
              type="success"
              closable
              @close="removeSaleAttrValue(row, $index)"
              v-for="(saleAttrValue, $index) in row.spuSaleAttrValueList"
              :key="row.id"
              >{{ saleAttrValue.saleAttrValueName }}</el-tag
            >
            <el-button
              v-if="!row.flag"
              type="primary"
              icon="Plus"
              size="small"
              @click="toAdd(row)"
            ></el-button>
            <el-input
              v-else
              v-model="row.inputValue"
              v-input-focus
              style="width: 140px"
              @blur="toLook(row)"
              placeholder="请输入属性值"
            ></el-input>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="140px" align="center">
          <template #="{ $index }">
            <el-button
              type="danger"
              icon="Delete"
              @click="deleteSaleAttr($index)"
            ></el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-form-item>
    <el-form-item>
      <el-button :disabled="!spuSaleAttr.length" type="primary" @click="addSpu"
        >保存</el-button
      >
      <el-button type="default" @click="$emit('updateContentShow', 0)">取消</el-button>
    </el-form-item>
  </el-form>
</template>

<script setup lang="ts">
import { ref, computed } from "vue";
import type {
  SpuObj,
  TrademarkObj,
  TrademarkResData,
  SpuImgResData,
  SpuImgObj,
  SpuSaleAttrObj,
  SpuSaleAttrResData,
  HasSaleAttrResData,
  HasSaleAttrObj,
} from "@/api/product/spu/types";
import {
  reqHasTrademark,
  reqSpuImageList,
  reqSpuSaleAttr,
  reqAllSaleAttr,
} from "@/api/product/spu";
import { ElMessage, type UploadProps, } from "element-plus";
import { reqAddOrEditSpu } from "@/api/product/spu";
const $emit = defineEmits(["updateContentShow"]);
// 收集表单数据
const formData = ref<SpuObj>({
  spuName: "",
  description: "",
  category3Id: "", //三级分类id
  tmId: "", // 品牌id
  spuSaleAttrList: [],
  spuImageList: [],
});
// 项目中所有的品牌
const allTrademark = ref<TrademarkObj[]>([]);
// 某个SPU下的照片列表
const imgList = ref<SpuImgObj[]>([]);
// 项目中所有的销售属性
const allSaleAttr = ref<HasSaleAttrObj[]>([]);
// 某个SPU下的销售属性
const spuSaleAttr = ref<SpuSaleAttrObj[]>([]);
// 控制dialog框中展示的照片
const dialogImageUrl = ref("");
// 控制dialog框的显示和隐藏
const dialogVisible = ref(false);
// 未选择的销售属性
let unSelectSaleAttr = ref<HasSaleAttrObj[]>([]);
// 销售属性选择框的提示
let tipInfo = ref('');
// 选择的销售属性
const selectedSaleAttr = ref('');

// 修改SPU时获取各部分数据
const updateSpuInitData = async (spu: SpuObj) => {
  // spu：父组件传递的spu数据【不完整】，需要补充使其完整
  formData.value = JSON.parse(JSON.stringify(spu));
  // 获取项目中所有品牌
  let result: TrademarkResData = await reqHasTrademark();
  if (result?.code === 200) {
    allTrademark.value = result?.data;
  }
  // 获取某个spu下商品的图片
  let result2: SpuImgResData = await reqSpuImageList(spu.id as number);
  if (result2?.code === 200) {
    // 将响应的数据进行标准化处理，不然组件识别不了
    imgList.value = result2?.data.map((item) => ({
      name: item.imgName,
      url: item.imgUrl,
    }));
  }
  // 获取当前的spu下的销售属性
  let result3: SpuSaleAttrResData = await reqSpuSaleAttr(spu.id as number);
  if (result3?.code === 200) {
    spuSaleAttr.value = result3?.data;
  }
  // 获取整个项目中全部的销售属性
  let result4: HasSaleAttrResData = await reqAllSaleAttr();
  if (result4?.code === 200) {
    allSaleAttr.value = result4?.data;
  }
};
// 添加SPU时获取各部分数据
const addSpuInitData = async(category3Id: number) =>{
  // 清空基本信息
  formData.value = {
    spuName: "",
    description: "",
    category3Id, //三级分类id
    tmId: "", // 品牌id
    spuSaleAttrList: [],
    spuImageList: [],
  }
  // 清空图片数据
  imgList.value = [];
  // 清空已有销售属性
  spuSaleAttr.value = [];
  // 清空选择框中的内容
  selectedSaleAttr.value = '';
  // 获取项目中所有品牌
  let result: TrademarkResData = await reqHasTrademark();
  if (result?.code === 200) {
    allTrademark.value = result?.data;
  }
  // 获取整个项目中全部的销售属性
  let result2: HasSaleAttrResData = await reqAllSaleAttr();
  if (result2?.code === 200) {
    allSaleAttr.value = result2?.data;
  }
}
// 计算属性计算出当前未选择的属性（欠缺，多练习数组方法）
unSelectSaleAttr = computed(() => {
  let unSelectAttr = allSaleAttr.value.filter((item) => {
    return spuSaleAttr.value.every((item2) => {
      return item.name !== item2.saleAttrName;
    })
  })
  return unSelectAttr;
})
// 计算属性计算出属性选择框的提示信息
tipInfo = computed(() => {
  return unSelectSaleAttr.value.length > 0 ? `还有${unSelectSaleAttr.value.length}个属性选择` : '没有属性可选择';
})
// 将组件中的方法对外暴露，以便父组件通过组件实例调用
defineExpose({
  updateSpuInitData,
  addSpuInitData,
  formData
});
// 照片上传服务器之前的回调（钩子）
const handlerUpload: UploadProps["beforeUpload"] = (rawFile) => {

  if (rawFile.type === 'image/jpeg' || rawFile.type === 'image/png' || rawFile.type === 'image/gif') {
    if (rawFile.size / 1024 / 1024 <= 4) {
      return true;
    } else {
      ElMessage.error('照片大小超过4M');
      return false;
    }
  } else {
    ElMessage.error('照片类型只支持jpg/png/gif');
    return false;
  }
};
// 照片预览的回调（钩子）
const handlePictureCardPreview: UploadProps["onPreview"] = (uploadFile) => {
  dialogImageUrl.value = uploadFile.url!;
  dialogVisible.value = true;
};
// 照片删除的回调（钩子）
const handleRemove: UploadProps["onRemove"] = () => { };
// 添加销售属性的回调
const addSaleAttr = () => {
  // 通过选择框收集的数据得到添加的属性id和属性名
  const [baseSaleAttrId, saleAttrName] = selectedSaleAttr.value.split(':');
  console.log(baseSaleAttrId, saleAttrName);

  // 向销售属性数组中添加一条记录
  // 添加完记录后，unSelectSaleAttr会重新计算，得到未添加的属性
  spuSaleAttr.value.push({
    baseSaleAttrId,
    saleAttrName,
    spuSaleAttrValueList: []
  });
  // 清除选择框的显示数据
  selectedSaleAttr.value = '';
}
// 添加销售属性值的回调
const toAdd = (row: SpuSaleAttrObj) => {
  // 显示输入框
  row.flag = true;
  // 清空输入框内容
  row.inputValue = '';
}
// 失去焦点，保存销售属性值回调
const toLook = (row: SpuSaleAttrObj) => {
  // 输入值为空，给出提示，函数终止执行
  if (!row.inputValue) {
    ElMessage.warning('属性值不能为空');
    return;
  }
  // 输入重复的值，给出提示，函数终止执行
  let repeat = row.spuSaleAttrValueList.some((item) => item.saleAttrValueName === row.inputValue);

  if (repeat) {
    ElMessage.warning('属性值重复，请重新输入');
    return;
  }
  // 将属性值对象放入属性值数组中
  row.spuSaleAttrValueList.push({
    // 不是存储 row.id
    baseSaleAttrId: row.baseSaleAttrId as number,
    saleAttrValueName: row.inputValue,
  })
  // 显示按钮
  row.flag = false;
}
// 删除销售属性的回调
const deleteSaleAttr = (index: number) => {
  // 删除表格展示的spuSaleAttr中的数据，unSelectAttr自动计算
  spuSaleAttr.value.splice(index, 1);
}
// 删除销售属性值的回调
const removeSaleAttrValue = (row: SpuSaleAttrObj, index: number) => {
  row.spuSaleAttrValueList.splice(index, 1);
}
// 保存按钮的回调
const addSpu = async () => {
  // 组装Spu的数据
  // 整理照片墙的数据
  formData.value.spuImageList = imgList.value.map((item:any)=>{
    return {
      imgName: item.name, // 图片的名字
      // 新上传的图片存在imgList里的内容是uploadFile
      imgUrl: (item.response&&item.response.data) || item.url
    }
  });
  console.log(formData.value.spuImageList);

  // 整理销售属性数据
  formData.value.spuSaleAttrList = spuSaleAttr.value;
  console.log(formData.value.spuSaleAttrList);

  let result: any = await reqAddOrEditSpu(formData.value);
  if (result?.code === 200) {
    ElMessage.success(`${formData.value.id ? '修改成功' : '新增成功'}`);
    $emit('updateContentShow', 0, formData.value.id? true : false);
  } else {
    ElMessage.error(`${formData.value.id ? '修改失败' : '新增失败'}`);
    $emit('updateContentShow', 0);
  }
}
</script>

<style scoped lang="scss">
.el-form {
  .el-form-item {
    &:last-child {
      margin-bottom: 0px;
    }
  }
}
</style>
